#include "webrtc_pub.hpp"
#include <cstring>

WebRTCClient::WebRTCClient(const std::string& robot_id)
    : robot_id_(robot_id),
      is_initialized_(false),
      is_connected_(false),
      data_channel_ready_(false),
      room_joined_(false),
      heartbeat_running_(false),
      ice_gathering_complete_(false),
      enable_compression_(true)  // 默认启用压缩
      ,
      draco_compression_level_(7) {  // 默认压缩级别为7
    std::cout << "WebRTC客户端已创建，机器人ID: " << robot_id_ << std::endl;
#ifdef HAS_DRACO
    std::cout << "Draco点云压缩已启用，压缩级别: " << draco_compression_level_ << std::endl;
#else
    std::cout << "Draco点云压缩不可用" << std::endl;
    enable_compression_ = false;
#endif
}

WebRTCClient::~WebRTCClient() {
    disconnect();
    std::cout << "WebRTC客户端已销毁" << std::endl;
}

bool WebRTCClient::initialize() {
    if (is_initialized_.load()) {
        std::cout << "WebRTC客户端已经初始化" << std::endl;
        return true;
    }

    try {
        rtc::InitLogger(rtc::LogLevel::Warning);
        is_initialized_.store(true);
        std::cout << "WebRTC客户端初始化成功" << std::endl;
        return true;
    } catch (const std::exception& e) {
        std::cerr << "WebRTC客户端初始化失败: " << e.what() << std::endl;
        return false;
    }
}

// 获取房间ID
std::string WebRTCClient::get_room_id() {
    CURL* curl;
    CURLcode res;
    std::string response_string;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://information-channel.cn/frontend/back-end/rt-webrtc/webrtc/create-room");

        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, "Accept: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);

        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);

        if (res == CURLE_OK) {
            try {
                json response_json = json::parse(response_string);
                if (response_json["code"] == 200 && response_json.contains("data")) {
                    std::string room_id = response_json["data"]["roomId"];
                    std::cout << "成功获取房间ID: " << room_id << std::endl;
                    return room_id;
                }
            } catch (const std::exception& e) {
                std::cerr << "解析房间ID响应失败: " << e.what() << std::endl;
            }
        }
    }
    return "";
}

// 连接房间
bool WebRTCClient::connect_to_room(const std::string& room_id) {
    if (!is_initialized_.load()) {
        std::cerr << "WebRTC客户端未初始化" << std::endl;
        return false;
    }

    current_room_id_ = room_id;

    // 连接WebSocket信令服务器
    websocket_ = std::make_shared<rtc::WebSocket>();
    std::string signaling_url =
        "wss://information-channel.cn/back-end/rt-signaling/signaling?token=valid_token&clientId=" + robot_id_ + "&clientType=HARDWARE_DEVICE";

    std::promise<bool> connection_promise;
    auto connection_future = connection_promise.get_future();

    websocket_->open(signaling_url);

    websocket_->onOpen([this, &connection_promise]() {
        std::cout << "\033[31mWebSocket连接已建立\033[0m" << std::endl;
        send_room_action("join-room");
        connection_promise.set_value(true);
    });

    websocket_->onError([&connection_promise](std::string error) {
        std::cerr << "WebSocket连接错误: " << error << std::endl;
        connection_promise.set_value(false);
    });

    websocket_->onMessage([this](auto data) {
        std::cout << "\033[34mwebsocket reveived......\033[0m" << std::endl;
        if (std::holds_alternative<std::string>(data)) {
            handle_websocket_message(std::get<std::string>(data));
        }
    });

    // 等待连接结果
    try {
        bool connected = connection_future.get();
        if (connected) {
            is_connected_.store(true);
            if (connection_callback_) {
                connection_callback_(true);
            }
        }
        return connected;
    } catch (const std::exception& e) {
        std::cerr << "连接到房间失败: " << e.what() << std::endl;
        return false;
    }
}

// TODO
bool WebRTCClient::send_point_cloud_data(const std::vector<float>& points) {
    if (!room_joined_.load()) {
        std::cerr << "尚未成功加入房间，无法发送数据" << std::endl;
        return false;
    }

    if (!data_channel_ready_.load()) {
        std::cerr << "数据通道未就绪" << std::endl;
        return false;
    }

    // 将float数组转换为JSON格式
    json point_cloud_json = json::array();
    for (size_t i = 0; i < points.size(); i += 4) {
        if (i + 2 < points.size()) {
            json point = {
                {"x", points[i]}, {"y", points[i + 1]}, {"z", points[i + 2]}, {"i", points[i + 3]}  // 使用实际强度值
            };
            point_cloud_json.push_back(point);
        }
    }

    std::cout << "发送点云数据，点数: " << point_cloud_json.size() << std::endl;

    return send_point_cloud_json(point_cloud_json);
}

bool WebRTCClient::send_point_cloud_json(const json& point_cloud_json) {
    if (!room_joined_.load()) {
        std::cerr << "尚未成功加入房间，无法发送数据" << std::endl;
        return false;
    }

    if (!data_channel_ready_.load()) {
        std::cerr << "数据通道未就绪" << std::endl;
        return false;
    }

    // 将JSON转换为二进制数据
    std::vector<uint8_t> binary_data = json_to_binary(point_cloud_json);
    if (binary_data.empty()) {
        std::cerr << "JSON转换为二进制数据失败" << std::endl;
        return false;
    }

    std::cout << "发送JSON点云数据，数据大小: " << binary_data.size() << " bytes" << std::endl;

    return send_binary_data(binary_data);
}

bool WebRTCClient::send_binary_data(const std::vector<uint8_t>& data) {
    if (!data_channel_ready_.load() || !data_channel_) {
        std::cerr << "数据通道未就绪" << std::endl;
        return false;
    }

    try {
        // 显示初始RTC缓存区状态
        size_t initial_buffer = data_channel_->bufferedAmount();
        std::cout << "🔍 发送前RTC缓存区状态: " << (initial_buffer / 1024.0) << " KB" << std::endl;

        // 记录总体开始时间
        auto total_start_time = std::chrono::high_resolution_clock::now();

        // 对数据进行切片，减去协议头的20字节
        auto chunks = slice_binary_data(data, MAX_DATA_CHANNEL_SIZE - 20);

        if (chunks.empty()) {
            std::cerr << "数据切片失败" << std::endl;
            return false;
        }

        uint32_t message_id = static_cast<uint32_t>(std::time(nullptr));

        // 发送每个分片
        for (size_t i = 0; i < chunks.size(); ++i) {
            // 检查并等待RTC缓存区可用
            wait_for_buffer_available();

            // 创建数据包：data_type 2表示JSON格式的点云数据
            auto packet = create_data_packet(message_id, static_cast<uint32_t>(i), static_cast<uint32_t>(chunks.size()), 1, chunks[i]);

            data_channel_->send(reinterpret_cast<const std::byte*>(packet.data()), packet.size());
            // 添加小延迟避免发送过快
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }

        // 计算总体发送耗时
        auto total_end_time = std::chrono::high_resolution_clock::now();
        auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(total_end_time - total_start_time);

        std::cout << "数据发送完成，总耗时: " << total_duration.count() << " ms" << std::endl;
        std::cout << "平均发送速率: " << (data.size() / 1024.0 / 1024.0) / (total_duration.count() / 1000.0) << " MB/s" << std::endl;
        std::cout << "\n========================================" << std::endl;
        return true;

    } catch (const std::exception& e) {
        std::cerr << "发送数据失败: " << e.what() << std::endl;
        return false;
    }
}

bool WebRTCClient::is_connected() const {
    return is_connected_.load();
}

bool WebRTCClient::is_data_channel_ready() const {
    return data_channel_ready_.load();
}

bool WebRTCClient::is_room_joined() const {
    return room_joined_.load();
}

size_t WebRTCClient::get_buffer_size() const {
    if (data_channel_) {
        return data_channel_->bufferedAmount();
    }
    return 0;
}

void WebRTCClient::disconnect() {
    // 发送离开房间消息
    if (is_connected_.load()) {
        send_room_action("leave-room");
        std::this_thread::sleep_for(std::chrono::milliseconds(500));  // 等待消息发送
    }

    stop_heartbeat();

    if (data_channel_) {
        data_channel_->close();
    }

    if (peer_connection_) {
        peer_connection_->close();
    }

    if (websocket_) {
        websocket_->close();
    }

    is_connected_.store(false);
    data_channel_ready_.store(false);
    room_joined_.store(false);

    if (connection_callback_) {
        connection_callback_(false);
    }

    std::cout << "WebRTC连接已断开" << std::endl;
}

void WebRTCClient::set_connection_callback(std::function<void(bool)> callback) {
    connection_callback_ = callback;
}

void WebRTCClient::set_data_received_callback(std::function<void(const std::vector<uint8_t>&)> callback) {
    data_received_callback_ = callback;
}

// TODO webrtc初始化
void WebRTCClient::init_webrtc() {
    std::cout << "🚀 开始初始化WebRTC..." << std::endl;

    rtc::Configuration config;
    config.iceServers.emplace_back("stun:stun.l.google.com:19302");
    peer_connection_ = std::make_shared<rtc::PeerConnection>(config);

    std::cout << "✅ PeerConnection已创建" << std::endl;

    // 设置WebRTC回调函数 - 必须在创建数据通道之前设置！
    // SDP回调
    peer_connection_->onLocalDescription([this](rtc::Description description) {
        if (description.typeString() == "offer") {
            json offer_data = create_offer_data(std::string(description));
            json send_info_msg = create_send_info_message(current_room_id_, offer_data);
            std::cout << "准备发送SDP Offer到服务器..." << std::endl;

            if (websocket_ && websocket_->readyState() == rtc::WebSocket::State::Open) {
                try {
                    std::cout << send_info_msg.dump(2) << std::endl;
                    websocket_->send(send_info_msg.dump());
                    std::cout << "✅ SDP Offer发送成功!" << std::endl;
                } catch (const std::exception& e) {
                    std::cerr << "❌ 发送SDP Offer时出错: " << e.what() << std::endl;
                }
            } else {
                std::cerr << "❌ WebSocket未连接，无法发送SDP Offer" << std::endl;
                if (websocket_) {
                    std::cerr << "   WebSocket状态: " << static_cast<int>(websocket_->readyState()) << std::endl;
                }
            }
        } else {
            std::cout << "⚠️  生成的SDP不是Offer类型: " << description.typeString() << std::endl;
        }
    });

    // ICE候选者回调
    peer_connection_->onLocalCandidate([this](rtc::Candidate candidate) {
        std::cout << "🔗 收集到本地ICE候选者" << std::endl;
        std::lock_guard<std::mutex> lock(ice_candidates_mutex_);
        local_ice_candidates_.push_back(std::string(candidate));
    });

    // 连接状态回调
    peer_connection_->onStateChange(
        [](rtc::PeerConnection::State state) { std::cout << "🔄 WebRTC连接状态变化: " << static_cast<int>(state) << std::endl; });

    // ICE收集状态回调
    peer_connection_->onGatheringStateChange([this](rtc::PeerConnection::GatheringState state) {
        if (state == rtc::PeerConnection::GatheringState::Complete) {
            std::cout << "✅ ICE收集完成，发送候选者批次..." << std::endl;
            ice_gathering_complete_.store(true);
            send_ice_candidate_batch();
        }
    });

    // 在设置所有回调后再创建数据通道
    setup_data_channel();
}

void WebRTCClient::setup_data_channel() {
    std::cout << "📡 正在创建数据通道..." << std::endl;

    try {
        data_channel_ = peer_connection_->createDataChannel("robot_channel");
        std::cout << "数据通道创建成功，标签: " << data_channel_->label() << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "创建数据通道失败: " << e.what() << std::endl;
        return;
    }

    data_channel_->onOpen([this]() {
        std::cout << "数据通道已打开，可以发送数据了！" << std::endl;
        data_channel_ready_.store(true);
        data_channel_->send("Hello from " + robot_id_);

        // 启动心跳
        std::cout << "启动websocket心跳......." << std::endl;
        start_heartbeat();
    });

    data_channel_->onClosed([this]() {
        std::cout << "数据通道已关闭" << std::endl;
        data_channel_ready_.store(false);
    });

    data_channel_->onMessage([this](auto data) {
        if (std::holds_alternative<std::vector<std::byte>>(data) && data_received_callback_) {
            auto& byte_data = std::get<std::vector<std::byte>>(data);
            std::vector<uint8_t> uint8_data(byte_data.size());
            memcpy(uint8_data.data(), byte_data.data(), byte_data.size());
            data_received_callback_(uint8_data);
        }
    });
}

std::string WebRTCClient::generate_message_id() {
    auto now = std::chrono::system_clock::now();
    auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
    return "MSG_" + std::to_string(timestamp);
}

std::string WebRTCClient::get_iso8601_timestamp() {
    auto now = std::chrono::system_clock::now();
    auto time_t_now = std::chrono::system_clock::to_time_t(now);
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;

    std::stringstream ss;
    ss << std::put_time(std::gmtime(&time_t_now), "%Y-%m-%dT%H:%M:%S");
    ss << '.' << std::setfill('0') << std::setw(3) << ms.count() << 'Z';
    return ss.str();
}

size_t WebRTCClient::WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t total_size = size * nmemb;
    std::string* response = static_cast<std::string*>(userp);
    response->append(static_cast<char*>(contents), total_size);
    return total_size;
}

// 实现缺失的私有方法
void WebRTCClient::send_room_action(const std::string& action_type) {
    if (!websocket_ || websocket_->readyState() != rtc::WebSocket::State::Open) {
        std::cerr << "WebSocket未连接，无法发送房间操作: " << action_type << std::endl;
        return;
    }

    json room_action = {{"type", action_type},
                        {"roomId", current_room_id_},
                        {"clientId", robot_id_},
                        {"clientType", "HARDWARE_DEVICE"},
                        {"timestamp", get_iso8601_timestamp()}};

    try {
        websocket_->send(room_action.dump());
        std::cout << "发送房间操作: " << action_type << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "发送房间操作失败: " << e.what() << std::endl;
    }
}

// TODO 处理WebSocket消息
void WebRTCClient::handle_websocket_message(const std::string& message) {
    try {
        json msg = json::parse(message);
        std::cout << "\033[31m收到WebSocket消息\033[0m: " << msg.dump(2) << std::endl;

        // 处理加入房间的响应
        if (msg.contains("type") && msg["type"] == "response") {
            if (msg.contains("code") && msg["code"] == 200 && msg.contains("message") && msg["message"] == "加入成功") {
                std::cout << "✅ 房间加入成功，开始初始化WebRTC并发送SDP..." << std::endl;
                room_joined_.store(true);

                // 初始化WebRTC
                init_webrtc();

                return;
            }
        }

        // 处理WebRTC信令消息
        if (msg.contains("type") && msg["type"] == "send-info") {
            if (msg.contains("data")) {
                json data = msg["data"];
                if (data.contains("type")) {
                    std::string data_type = data["type"];
                    if (data_type == "answer") {
                        std::cout << "answer SDP..............." << std::endl;
                        handle_answer(data);  // 设置SDP
                    } else if (data_type == "ice-candidate-batch") {
                        // std::cout<<"answer ICE..............."<<std::endl;
                        handle_ice_candidate(data);  // 设置ICE
                    }
                }
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "处理WebSocket消息失败: " << e.what() << std::endl;
    }
}

void WebRTCClient::handle_answer(const json& answer_data) {
    try {
        if (answer_data.contains("sdp")) {
            std::string sdp = answer_data["sdp"];
            rtc::Description answer(sdp, "answer");
            peer_connection_->setRemoteDescription(answer);
            std::cout << "\033[31m设置远程描述(answer)成功\033[0m" << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "处理answer失败: " << e.what() << std::endl;
    }
}

void WebRTCClient::handle_ice_candidate(const json& candidate_data) {
    try {
        // 根据webrtc-test的实现，检查ice数组格式
        if (candidate_data.contains("ice") && candidate_data["ice"].is_array()) {
            for (const auto& candidate : candidate_data["ice"]) {
                if (candidate.is_string()) {
                    std::string candidate_str = candidate;
                    std::cout << "----------" << std::endl;
                    std::cout << "收到ICE Candidate: " << candidate_str << std::endl;
                    std::cout << "----------" << std::endl;

                    peer_connection_->addRemoteCandidate(candidate_str);
                }
            }
            std::cout << "\033[31mICE Candidate batch添加成功\033[0m" << std::endl;
        } else {
            std::cout << "⚠️  ICE数据格式不正确或为空" << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "处理ICE候选者失败: " << e.what() << std::endl;
    }
}

void WebRTCClient::send_ice_candidate_batch() {
    std::lock_guard<std::mutex> lock(ice_candidates_mutex_);
    if (local_ice_candidates_.empty()) {
        return;
    }

    json ice_batch_data = create_ice_candidate_batch_data(local_ice_candidates_);
    json send_info_msg = create_send_info_message(current_room_id_, ice_batch_data);

    if (websocket_ && websocket_->readyState() == rtc::WebSocket::State::Open) {
        std::cout << send_info_msg.dump(2) << std::endl;
        websocket_->send(send_info_msg.dump());
        std::cout << "发送ICE候选者批次，数量: " << local_ice_candidates_.size() << std::endl;
    }

    local_ice_candidates_.clear();
}

json WebRTCClient::create_send_info_message(const std::string& room_id, const json& data) {
    return {{"type", "send-info"},
            {"roomId", room_id},
            {"clientId", robot_id_},
            {"data", data},
            {"timestamp", get_iso8601_timestamp()},
            {"from", robot_id_},
            {"messageId", generate_message_id()}};
}

json WebRTCClient::create_offer_data(const std::string& offer_sdp) {
    return {{"type", "offer"}, {"offer", offer_sdp}};
}

json WebRTCClient::create_ice_candidate_batch_data(const std::vector<std::string>& ice_candidates) {
    // 根据webrtc-test的格式，直接使用ice字段存储字符串数组
    json ice_data;
    ice_data["type"] = "ice-candidate-batch";
    ice_data["ice"] = ice_candidates;

    return ice_data;
}

std::vector<uint8_t> WebRTCClient::create_data_packet(uint32_t message_id,
                                                      uint32_t index,
                                                      uint32_t total,
                                                      uint32_t data_type,
                                                      const std::vector<uint8_t>& data) {
    std::vector<uint8_t> packet;
    packet.reserve(20 + data.size());

    // Magic number: 0x707063 - 大端写入
    uint32_t magic = 0x707063;                                     // 'cpp' in ASCII: 'c'=0x63, 'p'=0x70, 'p'=0x70
    packet.push_back(static_cast<uint8_t>((magic >> 24) & 0xFF));  // 高字节
    packet.push_back(static_cast<uint8_t>((magic >> 16) & 0xFF));
    packet.push_back(static_cast<uint8_t>((magic >> 8) & 0xFF));
    packet.push_back(static_cast<uint8_t>(magic & 0xFF));  // 低字节

    // Message ID - 大端写入
    packet.push_back(static_cast<uint8_t>((message_id >> 24) & 0xFF));
    packet.push_back(static_cast<uint8_t>((message_id >> 16) & 0xFF));
    packet.push_back(static_cast<uint8_t>((message_id >> 8) & 0xFF));
    packet.push_back(static_cast<uint8_t>(message_id & 0xFF));

    // Index - 大端写入
    packet.push_back(static_cast<uint8_t>((index >> 24) & 0xFF));
    packet.push_back(static_cast<uint8_t>((index >> 16) & 0xFF));
    packet.push_back(static_cast<uint8_t>((index >> 8) & 0xFF));
    packet.push_back(static_cast<uint8_t>(index & 0xFF));

    // Total - 大端写入
    packet.push_back(static_cast<uint8_t>((total >> 24) & 0xFF));
    packet.push_back(static_cast<uint8_t>((total >> 16) & 0xFF));
    packet.push_back(static_cast<uint8_t>((total >> 8) & 0xFF));
    packet.push_back(static_cast<uint8_t>(total & 0xFF));

    // Data type - 大端写入
    packet.push_back(static_cast<uint8_t>((data_type >> 24) & 0xFF));
    packet.push_back(static_cast<uint8_t>((data_type >> 16) & 0xFF));
    packet.push_back(static_cast<uint8_t>((data_type >> 8) & 0xFF));
    packet.push_back(static_cast<uint8_t>(data_type & 0xFF));

    // Data payload
    packet.insert(packet.end(), data.begin(), data.end());

    return packet;
}

std::vector<std::vector<uint8_t>> WebRTCClient::slice_binary_data(const std::vector<uint8_t>& data, size_t max_chunk_size) {
    std::vector<std::vector<uint8_t>> chunks;
    size_t total_size = data.size();

    for (size_t offset = 0; offset < total_size; offset += max_chunk_size) {
        size_t chunk_size = std::min(max_chunk_size, total_size - offset);
        std::vector<uint8_t> chunk(data.begin() + offset, data.begin() + offset + chunk_size);
        chunks.push_back(std::move(chunk));
    }

    return chunks;
}

void WebRTCClient::wait_for_buffer_available() {
    if (!data_channel_) {
        std::cerr << "数据通道未初始化" << std::endl;
        return;
    }

    size_t buffered_amount = data_channel_->bufferedAmount();
    int wait_count = 0;

    while (buffered_amount > RTC_BUFFER_THRESHOLD) {
        wait_count++;
        std::cout << "⚠️  RTC缓存区监控 #" << wait_count << ": " << (buffered_amount / 1024.0 / 1024.0) << " MB > "
                  << (RTC_BUFFER_THRESHOLD / 1024.0 / 1024.0) << " MB，等待10ms..." << std::endl;

        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        buffered_amount = data_channel_->bufferedAmount();

        // 避免无限等待，如果等待超过100次（1秒），输出警告
        if (wait_count > 100) {
            std::cout << "⚠️  缓存区持续满载超过1秒，可能存在网络问题" << std::endl;
            wait_count = 0;  // 重置计数器继续等待
        }
    }

    if (wait_count > 0) {
        std::cout << "✅ RTC缓存区恢复正常: " << (buffered_amount / 1024.0 / 1024.0) << " MB" << std::endl;
    }
}

void WebRTCClient::start_heartbeat() {
    if (heartbeat_running_.load()) {
        return;
    }

    heartbeat_running_.store(true);
    heartbeat_thread_ = std::thread(&WebRTCClient::heartbeat_loop, this);
}

void WebRTCClient::stop_heartbeat() {
    heartbeat_running_.store(false);
    if (heartbeat_thread_.joinable()) {
        heartbeat_thread_.join();
    }
}

void WebRTCClient::heartbeat_loop() {
    while (heartbeat_running_.load()) {
        std::this_thread::sleep_for(std::chrono::seconds(30));

        if (data_channel_ready_.load() && data_channel_) {
            try {
                std::string heartbeat_msg = "heartbeat:" + get_iso8601_timestamp();
                data_channel_->send(heartbeat_msg);
            } catch (const std::exception& e) {
                std::cerr << "发送心跳失败: " << e.what() << std::endl;
            }
        }
    }
}

// JSON点云数据转换为二进制数据
std::vector<uint8_t> WebRTCClient::json_to_binary(const json& point_cloud_json) {
    std::vector<uint8_t> binary_data;

    try {
        // 将JSON字符串化
        std::string json_string = point_cloud_json.dump();

        // 转换为二进制数据
        binary_data.resize(json_string.size());
        std::memcpy(binary_data.data(), json_string.c_str(), json_string.size());

        std::cout << "JSON转换为二进制数据完成，大小: " << binary_data.size() << " bytes" << std::endl;

    } catch (const std::exception& e) {
        std::cerr << "JSON转换异常: " << e.what() << std::endl;
        binary_data.clear();
    }

    return binary_data;
}

// Draco点云压缩相关实现
bool WebRTCClient::is_draco_available() const {
#ifdef HAS_DRACO
    return true;
#else
    return false;
#endif
}

// TODO 压缩点云发布
bool WebRTCClient::send_compressed_point_cloud(const std::vector<float>& points) {
    if (!room_joined_.load()) {
        std::cerr << "尚未成功加入房间，无法发送数据" << std::endl;
        return false;
    }

    if (!data_channel_ready_.load()) {
        std::cerr << "数据通道未就绪" << std::endl;
        return false;
    }

    try {
        // 尝试使用Draco压缩
        if (enable_compression_ && is_draco_available()) {
            std::vector<uint8_t> compressed_data = compress_point_cloud_draco(points);
            if (!compressed_data.empty()) {
                std::cout << "Draco压缩成功，原始大小: " << points.size() * sizeof(float) << " bytes，压缩后: " << compressed_data.size()
                          << " bytes，压缩比: " << (double)(points.size() * sizeof(float)) / compressed_data.size() << ":1" << std::endl;

                return send_binary_data(compressed_data);
            } else {
                std::cerr << "Draco压缩失败，回退到未压缩方式" << std::endl;
            }
        }

        // 如果压缩失败或不可用，使用原始方式
        return send_point_cloud_data(points);

    } catch (const std::exception& e) {
        std::cerr << "发送压缩点云数据时出错: " << e.what() << std::endl;
        return false;
    }
}

std::vector<uint8_t> WebRTCClient::compress_point_cloud_draco(const std::vector<float>& points) {
    std::vector<uint8_t> compressed_data;

#ifdef HAS_DRACO
    try {
        // 创建Draco点云对象
        auto point_cloud = create_draco_point_cloud(points);
        if (!point_cloud) {
            std::cerr << "创建Draco点云对象失败" << std::endl;
            return compressed_data;
        }

        // 编码点云
        compressed_data = encode_draco_point_cloud(*point_cloud);

    } catch (const std::exception& e) {
        std::cerr << "Draco压缩异常: " << e.what() << std::endl;
        compressed_data.clear();
    }
#else
    std::cerr << "Draco库不可用，无法进行压缩" << std::endl;
#endif

    return compressed_data;
}

#ifdef HAS_DRACO
std::unique_ptr<draco::PointCloud> WebRTCClient::create_draco_point_cloud(const std::vector<float>& points) {
    if (points.size() % 4 != 0) {
        std::cerr << "点云数据格式错误，点数据应为4的倍数（x,y,z,intensity）" << std::endl;
        return nullptr;
    }

    size_t num_points = points.size() / 4;
    if (num_points == 0) {
        std::cerr << "点云为空" << std::endl;
        return nullptr;
    }

    auto point_cloud = std::make_unique<draco::PointCloud>();
    point_cloud->set_num_points(num_points);

    // 添加位置属性 (x, y, z)
    draco::GeometryAttribute pos_att;
    pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3, draco::DT_FLOAT32, false, sizeof(float) * 3, 0);
    int pos_att_id = point_cloud->AddAttribute(pos_att, true, num_points);

    // 添加强度属性
    draco::GeometryAttribute intensity_att;
    intensity_att.Init(draco::GeometryAttribute::COLOR, nullptr, 1, draco::DT_FLOAT32, false, sizeof(float), 0);
    int intensity_att_id = point_cloud->AddAttribute(intensity_att, true, num_points);

    // 填充点云数据
    for (size_t i = 0; i < num_points; ++i) {
        // 设置位置数据
        float pos[3] = {points[i * 4], points[i * 4 + 1], points[i * 4 + 2]};
        point_cloud->attribute(pos_att_id)->SetAttributeValue(draco::AttributeValueIndex(i), pos);

        // 设置强度数据
        float intensity = points[i * 4 + 3];
        point_cloud->attribute(intensity_att_id)->SetAttributeValue(draco::AttributeValueIndex(i), &intensity);
    }

    return point_cloud;
}

std::vector<uint8_t> WebRTCClient::encode_draco_point_cloud(const draco::PointCloud& point_cloud) {
    std::vector<uint8_t> compressed_data;

    try {
        // 创建编码器
        draco::Encoder encoder;

        // 设置压缩参数
        encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 12);               // 位置量化位数
        encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC, 8);                 // 强度量化位数
        encoder.SetSpeedOptions(10 - draco_compression_level_, 10 - draco_compression_level_);  // 速度vs压缩比权衡

        // 编码点云
        draco::EncoderBuffer buffer;
        draco::Status status = encoder.EncodePointCloudToBuffer(point_cloud, &buffer);

        if (!status.ok()) {
            std::cerr << "Draco编码失败: " << status.error_msg() << std::endl;
            return compressed_data;
        }

        // 复制编码后的数据
        compressed_data.resize(buffer.size());
        std::memcpy(compressed_data.data(), buffer.data(), buffer.size());

    } catch (const std::exception& e) {
        std::cerr << "Draco编码异常: " << e.what() << std::endl;
        compressed_data.clear();
    }

    return compressed_data;
}
#endif